#!/usr/bin/env python

from kivy.logger import Logger

from kivy.app import App
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.scrollview import ScrollView
from kivy.uix.textinput import TextInput

from dryfire.view.messageView import MessageView
from dryfire.viewModel.rangesViewModel import RangesViewModel

__all__ = ('RangesView')

        
class _RangesRecordButton(Button, MessageView):
    def __init__(self, ident, description, vm_ranges_record_handler, **kargs):
        self.ident = ident
        if 'text' in kargs:
            del(kargs['text'])
        kargs['markup'] = True   
        kargs['on_press'] = self.w_handle_ranges_record_button_on_press
        kargs['size_hint'] = (1.0, None)
        kargs['height'] = dp(50)
        Button.__init__(self, **kargs)
        MessageView.__init__(self)
        self.description = None
        self.reset_text(description)
        self.vm_ranges_record_handler = vm_ranges_record_handler
        
    def reset_text(self, description):
        desc = description.strip()
        if desc != self.description:
            self.description = desc
            self.text = '[b]' + desc + '[/b]'
        
    def w_handle_ranges_record_button_on_press(self, instance):
        self.vm_ranges_record_handler(self.ident)
            

class _RangesListView(ScrollView):
    def __init__(self, vm_ranges_record_handler, **kargs):
        kargs['do_scroll_x'] = False
        ScrollView.__init__(self, **kargs)
        # view model command handling method
        self.vm_ranges_record_handler = vm_ranges_record_handler
        # create a default grid layout with custom width/height
        self._layout = GridLayout(cols=1,
                                  size_hint=(1.0, None))
        # when we add children to the grid layout, its size doesn't change at
        # all. we need to ensure that the height will be the minimum required to
        # contain all the childs. (otherwise, we'll child outside the bounding
        # box of the childs)
        self._layout.bind(minimum_height=self._layout.setter('height'))
        self.add_widget(self._layout)
        
    def log(self, ident, description):
        w = _RangesRecordButton(ident, description, self.vm_ranges_record_handler)
        y = self.scroll_y
        self._layout.add_widget(w)
        # if the scroll view was scrolled to the end
        # then stay at the end
        if y == 1.0:
            self.scroll_y = y
        return w


class RangesView(FloatLayout, MessageView):
    """a view for the domains page
        
        use bind_apply to bind the vm method to read and store the vars
        use bind_reset to bind the vm method to reset the vars

    """
    submit_command = 'Submit'
    create_command = 'Create A New Practice Target.'
    delete_command = 'Delete'
    edit_command = 'Edit'
    practice_command = 'Practice'
    
    commands = (practice_command, edit_command, delete_command)
    
    page_intro = "This page is where you can create, edit, delete and practice your targets."\
                 "\nYou can edit, delete or practice a target by clicking on its name in the list."

    def __init__(self, **kargs):
        FloatLayout.__init__(self, **kargs)
        MessageView.__init__(self)
        self._appdata = App.get_running_app().appdata
        self._appdata['ranges_view'] = self
        # page heading
        self.intro = Label(text=self.__class__.page_intro,
                           size_hint=(None, 0.4),
                           pos_hint={'center_x':0.5, 'y':0.6},
                           line_height=1.5)
        self.bind(width=self.on_width_handler)
        self.add_widget(self.intro)
        # initialize the view model
        view_model = RangesViewModel(self)
        # 'create new record' button
        self.create_button = Button(text=self.__class__.create_command,
                                 size_hint=(1.0, 0.2),
                                 pos_hint={'x':0.0, 'y':0.4})
        self.create_button.bind(on_press=view_model.w_handle_create_button_on_press)
        self.add_widget(self.create_button)
        # list of current domains
        self._list_view = _RangesListView(view_model.w_handle_ranges_record,
                                        size_hint=(1.0, 0.4),
                                        pos_hint={'x':0.0, 'y':0.0})
        self.add_widget(self._list_view)
        self._ranges = {}
        view_model.v_initialize_view()

    def on_width_handler(self, instance, value):
        if value > 40:
            value -= 20
        self.intro.text_size = (value-20, None)
 
    # vm methods

    def vm_add_range(self, ident, description):
        if ident not in self._ranges:
            self._ranges[ident] = self._list_view.log(ident, description)

    def vm_remove_ranges(self, ident_list):
        for ident in ident_list:
            if ident in self._ranges:
                self._ranges[ident].parent.remove_widget(self._ranges[ident])
                del(self._ranges[ident])

    def vm_show_range_added(self, ident, description):
        # inform user of the added ranges
        self.vm_add_range(ident, description)
        self.message_success('Added "%s"' % (description))
        
    def vm_show_range_edited(self, ident, description):
        if ident in self._ranges:
            self._ranges[ident].reset_text(description)
            # inform user of the edit
            self.message_success('Modified "%s"' % (description))

    def vm_show_range_deleted(self, ident):
        if ident in self._ranges:
            description = self._ranges[ident].description 
            self._ranges[ident].parent.remove_widget(self._ranges[ident])
            del(self._ranges[ident])
            # inform user of the deleted ranges
            self.message_success('Deleted "%s"' % (description))
